package com.innovation.ic.im.end.base.service.im_erp9.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.innovation.ic.b1b.framework.manager.RedisManager;
import com.innovation.ic.im.end.base.mapper.im_erp9.DialogueMapper;
import com.innovation.ic.im.end.base.model.im_erp9.Dialogue;
import com.innovation.ic.im.end.base.pojo.ServiceResult;
import com.innovation.ic.im.end.base.pojo.constant.Constants;
import com.innovation.ic.im.end.base.pojo.constant.RedisStorage;
import com.innovation.ic.im.end.base.service.helper.ServiceImplHelper;
import com.innovation.ic.im.end.base.service.im_erp9.DialogueService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * Dialogue的具体实现类
 */
@Service
@Transactional
public class DialogueServiceImpl extends ServiceImpl<DialogueMapper, Dialogue> implements DialogueService {

    @Resource
    private DialogueMapper dialogueMapper;

    @Resource
    private RedisManager redisManager;

    @Resource
    private DialogueService dialogueService;

    /**
     * 添加Dialogue对象
     *
     * @param dialogue
     * @return
     */
    @Override
    public ServiceResult<Boolean> saveDialogue(Dialogue dialogue) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<Boolean>();
        int insert = baseMapper.insert(dialogue);
        if (insert != 0) {
            // 删除redis中的话术数据
            ServiceImplHelper.getRedisManager().delRedisDataByKeyPrefix(RedisStorage.DIALOGUE_FIND_BY_ACCOUNT_ID_AND_GROUP_PREFIX + dialogue.getGroup() + RedisStorage.UNDERLINE + dialogue.getAccountId());
            // 导入最新的话术数据
            redisManager.set(RedisStorage.DIALOGUE_FIND_BY_ACCOUNT_ID_AND_GROUP_PREFIX + dialogue.getGroup() + RedisStorage.UNDERLINE + dialogue.getAccountId(), JSON.toJSONString(dialogueService.findByAccountIdAndGroupOrderByCreateTimeAsc(dialogue.getAccountId(), dialogue.getGroup())));
        }

        serviceResult.setMessage(ServiceResult.INSERT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 修改Dialogue对象
     *
     * @param dialogue
     * @return
     */
    @Override
    public ServiceResult<Boolean> updateDialogueById(Dialogue dialogue) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<Boolean>();
        dialogue.setUpdateTime(new Date());
        //获取原先的数据 用于清空redis缓存
        Dialogue dialogueData = baseMapper.selectById(dialogue.getId());
        int update = baseMapper.updateById(dialogue);
        if (update != 0) {
            // 删除redis中的话术数据
            redisManager.delRedisDataByKeyPrefix(RedisStorage.DIALOGUE_FIND_BY_ACCOUNT_ID_AND_GROUP_PREFIX + dialogueData.getGroup() + RedisStorage.UNDERLINE + dialogueData.getAccountId());
            if (dialogueData.getGroup().equals(dialogue.getGroup())) {//原来组与新的组是一样
                // 导入最新的话术数据
                redisManager.set(RedisStorage.DIALOGUE_FIND_BY_ACCOUNT_ID_AND_GROUP_PREFIX + dialogue.getGroup() + RedisStorage.UNDERLINE + dialogue.getAccountId(), JSON.toJSONString(dialogueService.findByAccountIdAndGroupOrderByCreateTimeAsc(dialogue.getAccountId(), dialogue.getGroup())));
            }
            //把原先的redis数据同步上去
            redisManager.set(RedisStorage.DIALOGUE_FIND_BY_ACCOUNT_ID_AND_GROUP_PREFIX + dialogueData.getGroup() + RedisStorage.UNDERLINE + dialogueData.getAccountId(), JSON.toJSONString(dialogueService.findByAccountIdAndGroupOrderByCreateTimeAsc(dialogueData.getAccountId(), dialogueData.getGroup())));
            // 导入最新的话术数据
            redisManager.set(RedisStorage.DIALOGUE_FIND_BY_ACCOUNT_ID_AND_GROUP_PREFIX + dialogue.getGroup() + RedisStorage.UNDERLINE + dialogueData.getAccountId(), JSON.toJSONString(dialogueService.findByAccountIdAndGroupOrderByCreateTimeAsc(dialogueData.getAccountId(), dialogue.getGroup())));
        }

        serviceResult.setMessage(ServiceResult.UPDATE_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 根据id，删除Dialogue对象
     *
     * @param id
     * @return
     */
    @Override
    public ServiceResult<Boolean> deleteDialogueById(Integer id) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<Boolean>();
        //获取原先的数据 用于清空redis缓存
        Dialogue dialogueData = baseMapper.selectById(id);
        int delete = baseMapper.deleteById(id);
        if (delete != 0) {
            // 删除redis中的话术数据
            redisManager.delRedisDataByKeyPrefix(RedisStorage.DIALOGUE_FIND_BY_ACCOUNT_ID_AND_GROUP_PREFIX + dialogueData.getGroup() + RedisStorage.UNDERLINE + dialogueData.getAccountId());
            // 导入最新的话术数据
            redisManager.set(RedisStorage.DIALOGUE_FIND_BY_ACCOUNT_ID_AND_GROUP_PREFIX + dialogueData.getGroup() + RedisStorage.UNDERLINE + dialogueData.getAccountId(), JSON.toJSONString(dialogueService.findByAccountIdAndGroupOrderByCreateTimeAsc(dialogueData.getAccountId(), dialogueData.getGroup())));
        }

        serviceResult.setMessage(ServiceResult.DELETE_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 根据id，置顶Dialogue对象
     *
     * @param id
     * @return
     */
    @Override
    public ServiceResult<Boolean> toppingDialogueById(Integer id) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<Boolean>();
        //获取原先的数据 用于清空redis缓存
        Dialogue dialogueData = baseMapper.selectById(id);
        Dialogue dialogue = new Dialogue();
        dialogue.setId(id);
        dialogue.setToppingTime(new Date());
        int update = baseMapper.updateById(dialogue);
        if (update != 0) {
            // 删除redis中的话术数据
            redisManager.delRedisDataByKeyPrefix(RedisStorage.DIALOGUE_FIND_BY_ACCOUNT_ID_AND_GROUP_PREFIX + dialogueData.getGroup() + RedisStorage.UNDERLINE + dialogueData.getAccountId());
            // 导入最新的话术数据
            redisManager.set(RedisStorage.DIALOGUE_FIND_BY_ACCOUNT_ID_AND_GROUP_PREFIX + dialogueData.getGroup() + RedisStorage.UNDERLINE + dialogueData.getAccountId(), JSON.toJSONString(dialogueService.findByAccountIdAndGroupOrderByCreateTimeAsc(dialogueData.getAccountId(), dialogueData.getGroup())));
        }

        serviceResult.setMessage(ServiceResult.UPDATE_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 按照分组和用户id，返回话术。已置顶的按照置顶时间降序排列，没置顶的按照创建时间升序排列
     *
     * @param group
     * @param erp9AdminsId
     * @return
     */
    @Override
    public ServiceResult<List<Dialogue>> findByAccountIdAndGroupOrderByToppingTimeDescAndCreateTimeAsc(String group, String erp9AdminsId) {
        ServiceResult<List<Dialogue>> serviceResult = new ServiceResult<List<Dialogue>>();

        QueryWrapper<Dialogue> queryWrapper = new QueryWrapper<Dialogue>();
        queryWrapper.eq("group_", group);
        queryWrapper.eq("account_id", erp9AdminsId);
        queryWrapper.orderByDesc("topping_time");
        queryWrapper.orderByAsc("create_time");
        List<Dialogue> dialogueList = baseMapper.selectList(queryWrapper);

        serviceResult.setResult(dialogueList);
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 从redis中获取数据按照分组和用户id，返回话术。已置顶的按照置顶时间降序排列，没置顶的按照创建时间升序排列
     *
     * @param group     组
     * @param accountId id
     * @return
     */
    @Override
    public ServiceResult<List<Dialogue>> findRedisByAccountIdAndGroupOrderByToppingTimeDescAndCreateTimeAsc(String group, String accountId) {
        ServiceResult<List<Dialogue>> serviceResult = new ServiceResult<>();
        // 从redis中获取dialogue数据
        List<Dialogue> resultList = new ArrayList<>();
        List<Dialogue> resultToppingTimeList = new ArrayList<>();//存放有置顶时间数据的集合
        List<Dialogue> resultcreateTimeList = new ArrayList<>();//存放有创建时间数据集合
        List<Dialogue> newResultList = new ArrayList<>();
        String lastContact = (String) redisManager.get(RedisStorage.DIALOGUE_FIND_BY_ACCOUNT_ID_AND_GROUP_PREFIX + group + RedisStorage.UNDERLINE + accountId);
        JSONObject json = (JSONObject) JSONObject.parse(lastContact);
        if (json != null && !json.isEmpty()) {
            JSONArray jsonArray = (JSONArray) json.get(Constants.RESULT);
            if (jsonArray != null && !jsonArray.isEmpty()) {
                resultList = JSONObject.parseArray(jsonArray.toJSONString(), Dialogue.class);
                for (Dialogue dialogue : resultList) {
                    if (dialogue.getToppingTime() != null) {
                        resultToppingTimeList.add(dialogue);
                    } else {
                        resultcreateTimeList.add(dialogue);
                    }
                }
                if (resultToppingTimeList != null && resultToppingTimeList.size() != 0) {
                    resultToppingTimeList.sort(Comparator.comparing(Dialogue::getToppingTime).reversed());
                    newResultList.addAll(resultToppingTimeList);
                }
                if (resultcreateTimeList != null && resultcreateTimeList.size() != 0) {
                    resultcreateTimeList.sort(Comparator.comparing(Dialogue::getCreateTime));
                    newResultList.addAll(resultcreateTimeList);
                }
            }
        }
        serviceResult.setResult(newResultList);
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 按照分组和用户id，返回话术。
     *
     * @param accountId
     * @param group
     * @return
     */
    @Override
    public ServiceResult<List<Dialogue>> findByAccountIdAndGroupOrderByCreateTimeAsc(String accountId, String group) {
        ServiceResult<List<Dialogue>> serviceResult = new ServiceResult<List<Dialogue>>();
        QueryWrapper<Dialogue> queryWrapper = new QueryWrapper<Dialogue>();
        queryWrapper.eq("group_", group);
        queryWrapper.eq("account_id", accountId);

        // 通过分组和用户id查询对应的话术并按照创建时间降序
        List<Dialogue> dialogueList = baseMapper.selectList(queryWrapper);
        serviceResult.setResult(dialogueList);
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 查询话术所有数据
     *
     * @return 返回查询结果
     */
    @Override
    public ServiceResult<List<Dialogue>> findByAccountIdAndGroup() {
        // 获取组与id
        List<Dialogue> dialogueList = dialogueMapper.findByAccountIdAndGroup();

        ServiceResult<List<Dialogue>> serviceResult = new ServiceResult<>();
        serviceResult.setResult(dialogueList);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        return serviceResult;
    }

    /**
     * 将dialogue表中的数据导入redis
     *
     * @return 返回导入结果
     */
    @Override
    public ServiceResult<Boolean> importDialogueIntoRedis() {
        ServiceResult<Boolean> returnResult = new ServiceResult<>();
        //获取话术所有数据
        ServiceResult<List<Dialogue>> serviceResult = findByAccountIdAndGroup();

        List<Dialogue> result = serviceResult.getResult();
        if (result != null && result.size() > 0) {
            for (Dialogue dialogue : result) {
                //数据存入redis
                addDialogueDataToRedis(dialogue.getAccountId(), dialogue.getGroup());
            }
        }

        returnResult.setMessage(ServiceResult.SYNC_SUCCESS);
        returnResult.setSuccess(Boolean.TRUE);
        returnResult.setResult(Boolean.TRUE);
        return returnResult;
    }

    /**
     * 添加话术数据到redis
     *
     * @param accountId id
     * @param group     组
     */
    private void addDialogueDataToRedis(String accountId, String group) {
        redisManager.set(RedisStorage.DIALOGUE_FIND_BY_ACCOUNT_ID_AND_GROUP_PREFIX + group + RedisStorage.UNDERLINE + accountId, JSON.toJSONString(findByAccountIdAndGroupOrderByCreateTimeAsc(accountId, group)));
    }
}